<?php

namespace Payment\Notify;

use Payment\Common\PayException;
use Payment\Common\SwThreeConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;


/**
 * Class SwNotify
 * 回调处理
 * @package Payment\Notify
 * @anthor yeran
 */
class SwThreeNotify extends NotifyStrategy
{

    /**
     * SwNotify constructor.
     * @param array $config
     * @throws PayException
     */
    public function __construct(array $config)
    {
        parent::__construct($config);

        try {
            $this->config = new SwThreeConfig($config);
        } catch (PayException $e) {
            throw $e;
        }
    }

    /**
     * 获取返回的异步通知数据
     * @return array|bool
     * @author yeran
     */
    public function getNotifyData()
    {
        $params = array();

        //支持直接读取input流
        $data = @file_get_contents('php://input');
        if(!empty($data)){
            $inputArray = json_decode($data,true);
            $params = array_merge($params,$inputArray);
        }

        if(count($params)<1){//如果参数为空,则不进行处理
            return false;
        }


        return $params;
    }

    /**
     * 检查异步通知的数据是否正确
     * @param array $data
     *
     * @author yeran
     * @return boolean
     */
    public function checkNotifyData(array $data)
    {
        if ($data['return_code'] != '01' || $data['result_code'] == '02') {
            return false;
        }

        // 检查返回数据签名是否正确
        return $this->verifySign($data);
    }

    /**
     * 检查微信返回的数据是否被篡改过
     * @param array $retData
     * @return boolean
     * @author yeran
     */
    protected function verifySign(array $retData)
    {
        $retSign = $retData['key_sign'];
        $data = ArrayUtil::removeKeys($retData, ['key_sign', 'pay_trace','pay_time','receipt_fee']);

        $values = [
            'return_code' => $data['return_code'],
            'return_msg' => $data['return_msg'],
            'result_code' => $data['result_code'],
            'pay_type' => $data['pay_type'],
            'user_id' => $data['user_id'],
            'merchant_name' => $data['merchant_name'],
            'merchant_no' => $data['merchant_no'],
            'terminal_id' => $data['terminal_id'],
            'terminal_trace' => $data['terminal_trace'],
            'terminal_time' => $data['terminal_time'],
            'total_fee' => $data['total_fee'],
            'end_time' => $data['end_time'],
            'out_trade_no' => $data['out_trade_no'],
            'channel_trade_no' => $data['channel_trade_no'],
            'attach' => $data['attach'],
        ];

        $values = ArrayUtil::paraFilter($values);
//        $values = ArrayUtil::arraySort($values);
        $signStr = ArrayUtil::createLinkstring($values);

        $signStr .= '&access_token=' . $this->config->access_token;
        switch ($this->config->signType) {
            case 'MD5':
                $sign = md5($signStr);
                break;
            default:
                $sign = '';
        }

        return strtoupper($sign) === strtoupper($retSign);
    }

    /**
     *
     * 封装回调函数需要的数据格式
     *
     * @param array $data
     *
     * @return array
     * @author yeran
     */
    protected function getRetData(array $data)
    {

        $retData = [
            'pay_type' => $data['pay_type'],//请求类型，010微信，020 支付宝，060qq钱包，080京东钱包，090口碑，100翼支付
            'user_id' => $data['user_id'],//付款方用户id，“微信openid”、“支付宝账户”、“qq号”等
            'merchant_name' => $data['merchant_name'],//商户名称
            'merchant_no' => $data['merchant_no'],//商户号
            'terminal_id' => $data['terminal_id'],//终端号
            'terminal_trace'  => $data['terminal_trace'],//终端流水号，此处传商户发起预支付或公众号支付时所传入的交易流水号
            'terminal_time' => $data['terminal_time'],//终端交易时间，yyyyMMddHHmmss，全局统一时间格式（01时参与拼接）
            'pay_trace'   => $data['pay_trace']??'',//当前支付终端流水号，与pay_time同时传递，返回时不参与签名
            'pay_time'   => $data['pay_time']??'',//当前支付终端交易时间，
            'total_fee' => $data['total_fee'],//金额，单位分
            'end_time'   =>  $data['end_time'],//支付完成时间，yyyyMMddHHmmss
            'out_trade_no'   => $data['out_trade_no'],//利楚唯一订单号
            'channel_trade_no' => $data['channel_trade_no'],//通道订单号，微信订单号、支付宝订单号等
            'attach'   => $data['attach'],//附加数据，原样返回
            'receipt_fee'   => $data['receipt_fee']??'',//口碑实收金额，pay_type为090时必填
            'channel'   => Config::SW_CHARGE,
        ];


        return $retData;
    }

    /**
     * 处理完后返回的数据格式
     * @param bool $flag
     * @param string $msg 通知信息，错误原因
     * @author yeran
     * @return array|mixed
     */
    protected function replyNotify($flag, $msg = 'OK')
    {
        // 默认为成功
        $return_code ='01';
        $return_msg ='数据校验成功，回调完成处理';
        if (! $flag) {
            $return_code ='02';
            $return_msg = '数据校验失败';
        }

        return [
            'return_code' => $return_code,
            'return_msg' => $return_msg,
        ];
    }
}
